extends "res://kerno/fenestroj/tipo_a1.gd"
# окно списка объектов


	# eligi - вывести
var eligi_distance = false # обновлять ли список объектов (дистанцию)


func _ready():
	var err = Title.connect("load_objekto", Callable(self, "_reload_objekto"))
	if err:
		print('ошибка установки реакции на load_objekto = ',err)

# перезагружаем список объектов
func _reload_objekto():
#	$"VBox/body_texture/ItemList".clear()
	$VBox/body_texture/Table.clear()
	FillItemList()


# заполнить список данными
func FillItemList():
	var item
	var i = 1
	var table = get_node("VBox/body_texture/Table")
	# если загружен космос, то берём список из объектов космоса
	if $"/root".get_node_or_null('space'):
		var _space = $"/root".get_node('space')
#		var _items = get_node("VBox/body_texture/ItemList")
		table.columns = 3
		table.set_hide_root(true)
		# заполняем заголовки столбцов
		table.set_column_title(0,'')
		table.set_column_title(1,'расстояние')
		table.set_column_title(2,'название')
		table.set_column_titles_visible(true)
		table.create_item()
		for ch in _space.get_children():
			if ch.is_in_group('create') and (not('directebla_sxipo' in ch)):
				item = table.create_item()
				# сохраняес данные строки, что бы точно идентифицировать
#				item.set_metadata(0,ch.duplicate(true)) - нельзя, т.к. дублируется не вся структура и главного нет
				item.set_metadata(0,ch)
				item.set_text(0,str(i))
				item.set_text(1,String(int(
					_space.get_node('ship').position.distance_to(ch.position))
					))
				item.set_metadata(1,ch.objekto['uuid'])
				item.set_text(2,ch.objekto['nomo']['enhavo'])
#				_items.add_item(
#					'('+String(int(
#					_space.get_node('ship').translation.distance_to(ch.translation))
#					)+') '+ch.objekto['nomo']['enhavo'], 
#					null, 
#					true
#				)
				i += 1
	else:
	# Заполняет список найдеными объектами
		for objekto in Global.objektoj:
			if not objekto.has('distance'):
				objekto['distance'] = 0
			item = table.create_item()
			# сохраняем данные строки, что бы точно идентифицировать
			item.set_metadata(0,objekto.duplicate(true))
			item.set_text(0,str(i))
			item.set_text(1,String(int(item['distance'])))
			item.set_metadata(1,objekto.objekto['uuid'])
			item.set_text(2,objekto['nomo']['enhavo'])
			i += 1
#			get_node("VBox/body_texture/ItemList").add_item(
#				'('+String(int(objekto['distance']))+') '+objekto['nomo']['enhavo'], 
#				null, 
#				true
#			)


func distance_to(trans):
	for obj in Global.objektoj:
		var new_distance = trans.distance_to(Vector3(obj['koordinatoX'],
			obj['koordinatoY'],obj['koordinatoZ']))
		if new_distance != obj['distance']:
			obj['distance']  = new_distance
			if not eligi_distance:
				$Timer.start()
				eligi_distance = true


func eligi_distance():
#	var index_pos = $'VBox/body_texture/ItemList'.get_selected_items()
#	print('distance_to')
	var tree = $VBox/body_texture/Table
	var select = tree.get_next_selected(null)
	if select:
		var objekto = select.get_metadata(0)
		# сохраняем uuid выделенного объекта
	#	var uuid_objekto = 
		print('objekto = ',objekto)
		print('===select 0 == ',select)
	_reload_objekto()

	if select:
		print('===select 1 == ',select)
#		select.select(0)
#		print('== objekto == ',objekto)
#		index_pos.move_to_bottom()
#		.select()
#		$VBox/body_texture/Table.select(index_pos)

#	if len(index_pos)>0:
#		$VBox/body_texture/Table.select(index_pos[0])


#		$'VBox/body_texture/ItemList'.select(index_pos[0])


func _on_ItemList_item_selected(index):
	print('234')
	if not $"/root".get_node_or_null('space'):
		return
	var objekto
	for child in Global.fenestro_kosmo.get_children():
		if child.is_in_group('create'):
			if child.uuid == Global.objektoj[index]['uuid']:
				objekto = child
				break
	if objekto:
		Global.fenestro_kosmo.node_objekto.set_objekto(objekto)
		if Global.logs:
			Title.get_node("CanvasLayer/komunikadoj").aldoni('Выделен объект - ' + objekto.objekto['uuid'])


# добавление объекта в список
# direktebla - признак, что создаём управляемый корабль
# возвращает индекс добавленного элемента в массике объектов
func aldoni_objekto(objekto, direktebla=false):
	var kol = -1
	# анализ и запрос данных для получения того, что храниться на складе
	if len(objekto['objektostokejoSet']['edges']) and\
		(Global.server or direktebla or Global.admin): 
		for stokejo in objekto['objektostokejoSet']['edges']:
			# запрашиваем, что хранится на складе
			Title.informmendo_stokejo(
				objekto['uuid'],
				objekto['uuid'],
				stokejo['node']['uuid'],
				''
			)
	for modulo in objekto['ligilo']['edges']:
#		if modulo['node']['tipo']['objId'] == 1: # связь типа 1 - модуль корабля
			# если есть склад/место хранения, и это сервер или свой корабль
			if len(modulo['node']['ligilo']['objektostokejoSet']['edges'])\
					and (Global.server or direktebla or Global.admin): 
				for stokejo in modulo['node']['ligilo']['objektostokejoSet']['edges']:
					# запрашиваем, что хранится на складе
					Title.informmendo_stokejo(
						objekto['uuid'],
						modulo['node']['ligilo']['uuid'],
						stokejo['node']['uuid'],
						''
					)
	if !direktebla:# если не управляемый корабль, то добавляем в список
		kol = len(Global.objektoj)
		Global.objektoj.append(objekto.duplicate(true))
		Global.objektoj[kol]['distance'] = 0
	return kol


# добавление объекта в список на базе станционного запроса с наличием связи нахождения внутри
#  то есть объект находится внутри другого объекта
# direktebla - признак, что создаём управляемый корабль
func aldoni_objekto_ligilo(ligilo, direktebla=false):
	var kol = aldoni_objekto(ligilo['ligilo'], direktebla)
	if kol>-1:# если объект добавлен в список, то добавляем uuid и другие поля связи
		Global.objektoj[kol]['ligiloLigilo'] = {
			'konektiloLigilo': ligilo['konektiloLigilo'],
			'konektiloPosedanto': ligilo['konektiloPosedanto'],
			'uuid': ligilo['uuid']
		}
		if ligilo['posedantoStokejo']:
			Global.objektoj[kol]['ligiloLigilo']['posedantoStokejo'] =\
				ligilo['posedantoStokejo'].duplicate(true)
		if ligilo['tipo']:
			Global.objektoj[kol]['ligiloLigilo']['tipo'] =\
				ligilo['tipo'].duplicate(true)


# ищем в объектах запись по типу связи и типу ресурса объекта при условии нахождения объекта внутри
# и возвращаем найденный элемент массива
func sercxo_tipo(tipoLigilo, tipoResuro):
	for objekto in Global.objektoj:
		if objekto.get('ligiloLigilo'):
			if (objekto['ligiloLigilo']['tipo']['objId'] == tipoLigilo and
				objekto['resurso']['objId'] == tipoResuro):
				return objekto
	return null


# функция возвращает справочник:
#   stop: true - нашли результат, false -результата нет, в след.параметре информация, есть-ли более глубокое место для поиска
#   result: либо нужно ли искать глубже (true), либо указатель на найденный объект
#
# процедура рекурсивного обхода вложенности объектов для поиска внутреннего объекта
func rikuro_sergxo_enmetajxo_objekto(objekto, posedi_uuid, nivelo):
	var result = {
		'stop':false,
		'result':false
	}
	for obj in objekto['ligilo']['edges']:
		#Должны искать сначало весь первый уровень, а потом входить на второй уровень внутри каждого, пройденного по первому, а то находится вложенный вместо требуемого первого уровня и вызывает ошибку
		if nivelo>0:
			if obj['node']['ligilo'].get('ligilo') and len(obj['node']['ligilo']['ligilo']['edges'])>0:
				result = rikuro_sergxo_enmetajxo_objekto(obj['node']['ligilo'], posedi_uuid, nivelo-1)
				if result['stop']:
					return result
		elif posedi_uuid == obj['node']['ligilo']['uuid']:
			result['stop'] = true
			result['result'] = obj['node']['ligilo']
		elif obj['node']['ligilo'].get('ligilo') and len(obj['node']['ligilo']['ligilo']['edges'])>0:
			result['result'] = true # есть уровень глубже
	return result


#  поиск вложенного объекта
# objekto - в каком объекте ищем
# posedi_uuid - uuid искомого объекта
func sergxo_enmetajxo_objekto(objekto, posedi_uuid):
	# признак необходимости продолжить цикл, т.к. есть более глубокие уровни поиска
	var indico = false #indico - признак
	# nivelo - уровень текущего требуемого анализа
	#nivelo - уровень
	var nivelo = 0
	var result = {
		'stop':false,
		'result':false
	}
	for obj in objekto['ligilo']['edges']:
		if posedi_uuid == obj['node']['ligilo']['uuid']:
			return obj['node']['ligilo']
		elif obj['node']['ligilo'].get('ligilo') and len(obj['node']['ligilo']['ligilo']['edges'])>0:
			indico = true # есть уровень глубже
			nivelo += 1

	while indico:
		indico = false
#			проходим по циклу до тех пор, пока есть уровни ниже
#			проходя по уровню, если метка уровня ниже лож и проверяемый уровень максимальный - проверяем, есть ли ещё ниже уровень, если есть меняем признак проверки на истину и по окончанию цикла увеличиваем глубину проверки и идём на начало цикла
		for obj in objekto['ligilo']['edges']:
			if obj['node']['ligilo'].get('ligilo') and len(obj['node']['ligilo']['ligilo']['edges'])>0:
				result = rikuro_sergxo_enmetajxo_objekto(obj['node']['ligilo'], posedi_uuid, nivelo-1)
				if result['stop']:
					return result['result']
				if result['result']:
					indico = true
		nivelo += 1
	return false


func analizo_shanghi_ligilo(ligil, shanghi_ligilo, objekto_sxangxi):
	"""
	анализируем в этой ли связи произошло изменение и производим изменение
	возвращаем true - если связь найдена
	"""
	var result = false
	if shanghi_ligilo:
		# изменения произошли в связи
		if ligil['uuid'] == shanghi_ligilo['uuid']:
			# изменение в данной связи
			result = true
	else: # изменение произошли в объекте
		if ligil['ligilo']['uuid'] == objekto_sxangxi['uuid']:
			# изменение в данном объекте
			ligil['ligilo'] = {}
			ligil['ligilo'] = objekto_sxangxi.duplicate(true)
			result = true
	return result


# редактируем данные связи внутри списка согласно пришедшим данным
func sxangxi_ligilo(fadeno_ligilo, shanghi_ligilo, objekto_sxangxi):
	"""
	редактируем данные связи внутри списка согласно пришедшим данным
	fadeno_ligilo - в какой ветке произошло изменение
	shanghi_ligilo - в какой конкретно связи произошло изменение
	objekto_sxangxi - в каком объекте произошло изменение
	"""
	var shanghi = false # были ли произведены изменение
	var i_objekto = 0 # индекс объекта для удаления (корабль вылетел со станции)
	# ищем объект с такой связью
	# поиск в управляемом корабле
	if Global.direktebla_objekto[Global.realeco-2]['ligiloLigilo']['edges'].front()['node']['uuid'] ==\
		fadeno_ligilo['uuid']:
		if shanghi_ligilo['posedantoStokejo']:
			# объект находится в складе
			if shanghi_ligilo['forigo']:
				forigo_modulo_stokejo(Global.direktebla_objekto[Global.realeco-2],
					shanghi_ligilo['posedantoStokejo']['uuid'],
					shanghi_ligilo['ligilo']['uuid'])
			else:
				pass # получение не доработано
		return
	for objekto in Global.objektoj:
		if objekto.get('ligiloLigilo') and objekto['ligiloLigilo']['uuid'] == fadeno_ligilo['uuid']:
			if shanghi_ligilo['posedantoStokejo']:
				# объект находится в складе
				if shanghi_ligilo['forigo']:
					forigo_modulo_stokejo(objekto,
						shanghi_ligilo['posedantoStokejo']['uuid'],
						shanghi_ligilo['ligilo']['uuid'])
				else:
					# получение не доработано
					if objekto.get('stokejo'):
						sxangxi_stokejo_objekto(objekto['stokejo'], shanghi_ligilo['ligilo'])
					else:
						print(' НЕТ СКЛАДА - НУЖНО ДОБАВИТЬ ИЛИ ОШИБКА ДАННЫХ!!!')
				return
			else:
				if shanghi_ligilo and objekto['ligiloLigilo']['uuid'] == shanghi_ligilo['uuid']:
					Global.objektoj.remove(i_objekto) # удалена связь первого уровня (например - корябль вышел из дока)
					if not shanghi_ligilo['forigo']: # если была изменена, то добавляем новые данные
						aldoni_objekto_ligilo(shanghi_ligilo)
					return
				var i_ligil2 = 0 
				# изменение в данной ветке
				for ligil2 in objekto['ligilo']['edges']:
					shanghi = analizo_shanghi_ligilo(ligil2['node'], shanghi_ligilo, objekto_sxangxi)
					if shanghi:
						if shanghi_ligilo:
							objekto['ligilo']['edges'].remove(i_ligil2)# удаляем связь
							if not shanghi_ligilo['forigo']:# вносим новые данные
								objekto['ligilo']['edges'].append(shanghi_ligilo.duplicate(true))
						return
					var i_ligil3 = 0
					for ligil3 in ligil2['node']['ligilo']['ligilo']['edges']:
						# более глубокое вложение
						shanghi = analizo_shanghi_ligilo(ligil3['node'], shanghi_ligilo, objekto_sxangxi)
						if shanghi:
							if shanghi_ligilo:
								print('== удаляем связь 2')
								ligil2['node']['ligilo']['ligilo']['edges'].remove(i_ligil3)# удаляем связь
								if not shanghi_ligilo['forigo']:# вносим новые данные
									ligil2['node']['ligilo']['ligilo']['edges'].append(shanghi_ligilo.duplicate(true))
							return
						i_ligil3 += 1
					i_ligil2 += 1
				if not shanghi:
					# изменения не были внесены, значит нужно добавить связь/объект
					if shanghi_ligilo:
						var per = {
							'node': shanghi_ligilo.duplicate(true)
						}
						objekto['ligilo']['edges'].append(per.duplicate(true))
						return
			
		if shanghi:
			return
		i_objekto += 1
	if not shanghi:
		# изменения не были внесены, значит нужно добавить связь/объект
		if shanghi_ligilo:
			aldoni_objekto_ligilo(shanghi_ligilo)


# изменяем объект в складе. Если объекта нет, то добавляем
func sxangxi_stokejo_objekto(stokejo, objekto):
	var aldoni = true
	for stokej in stokejo:
		for objekto_stokejo in stokej['objekto']['edges']:
			if objekto_stokejo['node']['uuid'] == objekto['uuid']:
				# изменяем данные объекта
				print('== не доработано, нужно внести изменения')
				pass
	if aldoni:
		# добавление не произошло, добавляем
		var per = {
			'node': objekto.duplicate(true)
		}
		stokejo.front()['objekto']['edges'].append(per.duplicate(true))

# удаляем объект из склада объекта (elementoj), согласно пришедшему изменению по подписке
# stokejo_uuid - uuid места хранения (склада)
# objekto_uuid - uuid удаляемого объекта
func forigo_elemento_stokejo_subscription(elementoj,stokejo_uuid, objekto_uuid):
	if !elementoj.get('stokejo'):
		return
	else:
		for objekto_stokejo in elementoj['stokejo']:
			if objekto_stokejo['uuid'] == stokejo_uuid:
				# проверяем, есть-ли такой элемент в складе
				var i = 0 # счётчик номера для удаляемого элемента списка
				for objekt in objekto_stokejo['objekto']['edges']:
					if objekt['node']['uuid'] == objekto_uuid:
						#изменяем значения элемента внутри склада
						objekto_stokejo['objekto']['edges'].remove(i)
						return
					i += 1 


# изменить объект в складе, согласно пришедшему изменению по подписке
func sxangxi_elemento_stokejo_subscription(elementoj,item):
	var aldoni = true
	if !elementoj.get('stokejo'):
			elementoj['stokejo'] = []
	else:
		for objekto_stokejo in elementoj['stokejo']:
			if objekto_stokejo['uuid'] == item['ligiloLigilo']['edges'].front()['node']['posedantoStokejo']['uuid']:
				# проверяем, есть-ли такой элемент в складе
				var aldoni_objekto_var = true # объект не найден, нужно добавить
				for objekt in objekto_stokejo['objekto']['edges']:
					if objekt['node']['uuid'] == item['uuid']:
						aldoni_objekto_var = false
						#изменяем значения элемента внутри склада
						objekt['node']['volumenoEkstera'] = item['volumenoEkstera']
						objekt['node']['volumenoInterna'] = item['volumenoInterna']
						objekt['node']['volumenoStokado'] = item['volumenoStokado']
				if aldoni_objekto_var:
					# добавляем элементы внутрь склада
					objekto_stokejo['objekto']['edges'].append({
						'node': {
							'integreco': 0,
							'nomo': item['nomo'],
							'stato': item['stato'],
							'resurso':item['resurso'],
							'uuid': item['uuid'],
							'volumenoEkstera': item['volumenoEkstera'],
							'volumenoInterna': item['volumenoInterna'],
							'volumenoStokado': item['volumenoStokado']
						}
					})
				aldoni = false
				break
	if aldoni:
		elementoj['stokejo'].append({
			'nomo': item['ligiloLigilo']['edges'].front()['node']['posedantoStokejo']['nomo'],
			'priskribo': item['ligiloLigilo']['edges'].front()['node']['posedantoStokejo']['priskribo'],
			'uuid': item['ligiloLigilo']['edges'].front()['node']['posedantoStokejo']['uuid'],
			'posedantoObjekto': item['ligiloLigilo']['edges'].front()['node']['posedanto']['uuid'],
			'objekto':{
				'edges':[{
					'node': {
							'integreco': 0,
							'nomo': item['nomo'],
							'stato': item['stato'],
							'uuid': item['uuid'],
							'volumenoEkstera': item['volumenoEkstera'],
							'volumenoInterna': item['volumenoInterna'],
							'volumenoStokado': item['volumenoStokado']
						}
				}]
			}
		})


# добавить элементы (содержание) в склад
# elementoj - объект, в котором находится склад из списка Global.objektoj или внутренних его частей
# stokejo - склад
# из передаваемого (stokejo) склада объекты помещаются в склад передаваемого (elementoj) объекта
# если склада не было - создаётся
func aldoni_elemento_stokejo(elementoj,stokejo, skip=false):
	var aldoni = true
	if !elementoj.get('stokejo'):
		elementoj['stokejo'] = []
	else:
		for objekto_stokejo in elementoj['stokejo']:
			if objekto_stokejo['uuid'] == stokejo['uuid']:
				# добавляем элементы внутрь склада
				aldoni = false
				for objekt in stokejo['objekto']['edges']:
					objekto_stokejo['objekto']['edges'].append(objekt.duplicate(true))
				break
	if aldoni:
			elementoj['stokejo'].append(stokejo.duplicate(true))


# добавляем данные склада в модуль
func aldoni_modulo_stokejo(objekto, uuid_modulo, stokejo):
	if objekto['uuid'] == uuid_modulo:
		aldoni_elemento_stokejo(objekto,stokejo)
	else:
		for modulo in objekto['ligilo']['edges']:
			if modulo['node']['ligilo']['uuid'] == uuid_modulo: 
				aldoni_elemento_stokejo(modulo['node']['ligilo'],stokejo)


# добавить содержание в склад
# aldoni - добавить объекты из склада (stokejo) в склад
func aldoni_objektoj_stokejo(uuid_objekto, uuid_modulo, stokejo):
	if uuid_objekto == Global.direktebla_objekto[Global.realeco-2]['uuid']:
		aldoni_modulo_stokejo(Global.direktebla_objekto[Global.realeco-2],
			uuid_modulo, stokejo)
	else:
		for objekto in Global.objektoj:
			if objekto['uuid'] == uuid_objekto:
				aldoni_modulo_stokejo(objekto, uuid_modulo, stokejo)
	# обновление в космосе:
	if Global.fenestro_kosmo:
		Global.fenestro_kosmo.aldoni_objekto_stokejo(
			uuid_objekto,
			uuid_modulo,
			stokejo
		)
	Title.get_node("CanvasLayer/UI/UI/konservejo").plenigi_formularon()


# удалить объект из склада
# elementoj - объект (модуль объекта), в котором находится склад 
# uuid_forigo_objekto - удаляемый объект
func forigo_elemento_stokejo(elementoj, uuid_stokejo, uuid_forigo_objekto, skip=false):
	if !elementoj.get('stokejo'):
		return
	else:
		for objekto_stokejo in elementoj['stokejo']:
			if objekto_stokejo['uuid'] == uuid_stokejo:
				var i_stokejo = 0
				for objekto in objekto_stokejo['objekto']['edges']:
					if objekto['node']['uuid'] == uuid_forigo_objekto:
						# удаляем объект
						objekto_stokejo['objekto']['edges'].remove(i_stokejo)
						return
					i_stokejo += 1


# удаляем данный объект из склада модуля
func forigo_modulo_stokejo(objekto, uuid_stokejo, uuid_forigo_objekto):
	if objekto.get('objektostokejoSet') and len(objekto['objektostokejoSet']['edges'])>0:
		for stokejoj in objekto['objektostokejoSet']['edges']:
			if stokejoj['node']['uuid'] == uuid_stokejo:
				forigo_elemento_stokejo(objekto, uuid_stokejo, uuid_forigo_objekto)
	else:
		for modulo in objekto['ligilo']['edges']:
			if len(modulo['node']['ligilo']['objektostokejoSet']['edges'])>0:
				for stokejoj in modulo['node']['ligilo']['objektostokejoSet']['edges']:
					if stokejoj['node']['uuid'] == uuid_stokejo:
						forigo_elemento_stokejo(modulo['node']['ligilo'], uuid_stokejo, uuid_forigo_objekto)


# удалить объект из содержащегося в складе
# uuid_objekto - объект, в котором удаляем
# uuid_stokejo - склад, в котором удаляемый объект
# uuid_forigo_objekto - удаляемый объект
func forigo_objektoj_stokejo(uuid_objekto, uuid_stokejo, uuid_forigo_objekto):
#uuid склада - по нему ищем склад - аналог uuid_modulo
	if uuid_objekto == Global.direktebla_objekto[Global.realeco-2]['uuid']:
		forigo_modulo_stokejo(Global.direktebla_objekto[Global.realeco-2],
			uuid_stokejo, uuid_forigo_objekto)
	else:
		for objekto in Global.objektoj:
			if objekto['uuid'] == uuid_objekto:
				forigo_modulo_stokejo(objekto, uuid_stokejo, uuid_forigo_objekto)
#	# обновление в космосе:
	if Global.fenestro_kosmo:
		# не зделано
		pass
	Title.get_node("CanvasLayer/UI/UI/konservejo").plenigi_formularon()


func _focus_entered():
	fenestro_supren()


func _on_Timer_timeout():
	if eligi_distance:
		eligi_distance()
	eligi_distance = false




func _on_Table_item_selected():
	print('_on_Table_item_selected')
	var tree = $VBox/body_texture/Table
	var select = tree.get_next_selected(null)
	if select:
		var objekto_uuid = select.get_metadata(1)
		print('objekto_uuid = ',objekto_uuid)
		# сохраняем uuid выделенного объекта
	#	var uuid_objekto = 
